/*
 * Copyright 2006 Integrated Ocean Drilling Program US Implementing Organization.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package scala.maven;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * Abstract parent of all Scala Mojo
 */
public abstract class ScalaMojo extends CommandMojo {


	/**
	 * @parameter
	 */
	protected String minmemory;
	
	/**
	 * @parameter
	 */
	protected String maxmemory;

	/**
     * Project classpath.
     *
     * @parameter expression="${project.compileClasspathElements}"
     * @required
     * @readonly
     */
    protected List<String> classpathElements;

    protected String scalaHome;
    protected String javaBin;

    public void execute() throws MojoExecutionException, MojoFailureException {
        super.execute();
        javaBin = System.getProperty("java.home");
        if (javaBin == null) {
            javaBin = System.getenv("JAVA_HOME");
            if (javaBin == null) {
                throw new MojoExecutionException("Couldn't locate java, try setting JAVA_HOME environment variable.");
            }
        }
        javaBin += File.separator + "bin" + File.separator + "java";

    }

    public static String join(Collection<String> s, String delimiter) {
        StringBuffer buffer = new StringBuffer();
        Iterator iter = s.iterator();
        while (iter.hasNext()) {
            buffer.append(iter.next());
            if (iter.hasNext()) {
                buffer.append(delimiter);
            }
        }
        return buffer.toString();
    }

    protected String getClassPath(List<String> classPathElements) {
        return join(classPathElements, File.pathSeparator);
    }


    protected void performCompile(final File outputDir, final File sourceDir, final List<String> classpathElements, final boolean deprecationWarnings, final boolean uncheckedWarnings, final boolean useFsc) throws MojoExecutionException {
        if (!outputDir.exists())
            outputDir.mkdirs();

        // no source directory found
        if (!sourceDir.exists())
            return;

        List<String> sourceFiles;
        try {
            sourceFiles = findFiles(sourceDir, File.separator, ".*\\.scala");
        } catch (Exception e) {
            throw new MojoExecutionException("exception occured while finding scala source files in " + sourceDir.getAbsolutePath(), e);
        }

        // no source files found
        if (sourceFiles.isEmpty())
	{
	    getLog().debug("No source files found.");
            return;
	}

        List<String> command = new ArrayList<String>();
        command.add(javaBin);
        //see below
        addMemoryOptions(command);
        command.add("-classpath");
        command.add(getClassPath(classpathElements));
        command.add(useFsc ? "scala.tools.nsc.CompileClient" : "scala.tools.nsc.Main");
        command.add("-d");
        command.add(outputDir.getAbsolutePath());

        if (deprecationWarnings)
            command.add("-deprecation");
        if (uncheckedWarnings)
            command.add("-unchecked");

        command.add("-sourcepath");
        command.add(sourceDir.getAbsolutePath());
        for (String x : sourceFiles) {
            command.add(sourceDir + File.separator + x);
        }
        runCommand(command.toArray(new String[0]));
    }

    //figure out a better way to do this
    protected void addMemoryOptions(List<String> command)
    {
    	if (minmemory != null)
    		command.add("-Xms" + minmemory);
    	if (maxmemory != null)
    		command.add("-Xmx" + maxmemory);
    }
}
